package zack.project.domain.activity.service.quota;

import zack.project.domain.activity.adapter.repository.IActivityRepository;
import zack.project.domain.activity.model.aggregate.CreateQuotaOrderAggregate;

import zack.project.domain.activity.model.entity.*;
import zack.project.domain.activity.model.valobj.OrderTradeTypeVO;
import zack.project.domain.activity.service.IRaffleActivityAccountQuotaService;
import zack.project.domain.activity.service.IRaffleActivitySkuStockService;
import zack.project.domain.activity.service.quota.policy.ITradePolicy;
import zack.project.domain.activity.service.quota.rule.IActionChain;
import zack.project.domain.activity.service.quota.rule.factory.DefaultActivityChainFactory;
import zack.project.types.enums.ResponseCode;
import zack.project.types.exception.AppException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.math.BigDecimal;
import java.util.Map;

/**
 * @author A1793
 */                                           //要先继承类再实现接口
@Slf4j
public abstract class AbstractRaffleActivityAccountQuota extends RaffleActivityAccountQuotaSupport
        implements IRaffleActivityAccountQuotaService, IRaffleActivitySkuStockService {


    private final Map<String, ITradePolicy> tradePolicyGroup;

    public AbstractRaffleActivityAccountQuota(IActivityRepository activityRepository,
                                              DefaultActivityChainFactory defaultActivityChainFactory,
                                              Map<String, ITradePolicy> tradePolicyGroup) {
        super(activityRepository, defaultActivityChainFactory);
        this.tradePolicyGroup = tradePolicyGroup;
    }

    /**
     * 这个sku充值单可能是由用户行为返利产生的不需要支付的充值单，也可能是消耗积分进行兑换的充值单
     * @param skuRechargeEntity
     * @return
     */
    @Override
    public UnpaidActivityOrderEntity createOrder(SkuRechargeEntity skuRechargeEntity) {
        log.info("创建活动参与单开始 userId:{}", skuRechargeEntity.getUserId());
        //获取次数充值订单的参数
        Long sku = skuRechargeEntity.getSku();
        String userId = skuRechargeEntity.getUserId();

        if (sku == null || StringUtils.isEmpty(userId)) {
            throw new AppException(ResponseCode.ILLEGAL_PARAMETER.getCode(), ResponseCode.ILLEGAL_PARAMETER.getInfo());
        }
        //如果是需要支付的订单,查询是否有未支付的活动参与单
        if (OrderTradeTypeVO.credit_pay_trade.equals(skuRechargeEntity.getOrderTradeTypeVO())) {
            log.info("存在未支付的参与单 userId:{}", userId);
            //查询数据库表{raffle_activity_order}是否有未使用的充值单
            UnpaidActivityOrderEntity unpaidActivityOrderEntity = activityRepository
                    .queryUnpaidActivityOrder(skuRechargeEntity);
            if (unpaidActivityOrderEntity != null) {
                return unpaidActivityOrderEntity;
            }
        }
        //sku -> activityId -> activityEntity -> activityCountId -> activityCountEntity
        //查询数据库表{raffle_activity_sku}获取sku实体对象
        ActivitySkuEntity activitySkuEntity = queryActivitySku(sku);
        //查询数据库表{raffle_activity}获取活动实体对象
        ActivityEntity activityEntity = queryRaffleActivityByActivityId(activitySkuEntity.getActivityId());
        //查询该活动和sku下的抽奖次数配置
        ActivityCountEntity activityCountEntity =
                queryRaffleActivityCountByActivityCountId(activitySkuEntity.getActivityCountId());

        //如果是需要用积分支付的充值订单需要先查询用户的积分账户的积分是否足够
        if (OrderTradeTypeVO.credit_pay_trade.equals(skuRechargeEntity.getOrderTradeTypeVO())) {
            //查询用户积分账户{user_credit_account}中可用的积分数
            BigDecimal availableAmount = activityRepository.queryUserCreditAccountAmount(userId);
            if (availableAmount.compareTo(activitySkuEntity.getProductAmount()) < 0) {
                throw new AppException(ResponseCode.USER_CREDIT_ACCOUNT_NO_AVAILABLE_AMOUNT.getCode(),
                        ResponseCode.USER_CREDIT_ACCOUNT_NO_AVAILABLE_AMOUNT.getInfo());
            }
        }
        log.info("活动规则过滤-【责任链】 userId:{}", userId);
        //责任链过滤，过滤活动的基础信息{activity}(活动状态，开启结束时间)和尝试扣减活动sku商品{raffle_activity_sku}的库存余量
        IActionChain iActionChain = defaultActivityChainFactory.openActionChain();
        //判断活动时间是否正常以及尝试修改sku商品的库存
        iActionChain.action(activitySkuEntity, activityEntity, activityCountEntity);
        //创建调额聚合实体,包含要充值的次数和活动充值单
        CreateQuotaOrderAggregate createQuotaOrderAggregate = buildOrderAggregate(skuRechargeEntity,
                activitySkuEntity,
                activityEntity,
                activityCountEntity);
        //根据充值订单中的交易类型来获得对应的处理交易的节点
        ITradePolicy tradeService = tradePolicyGroup.get(skuRechargeEntity.getOrderTradeTypeVO().getCode());
        //将调额聚合对象传给交易节点
        tradeService.trade(createQuotaOrderAggregate);

        return UnpaidActivityOrderEntity.builder()
                .userId(userId)
                .orderId(createQuotaOrderAggregate.getActivityOrderEntity().getOrderId())
                .outBusinessNo(skuRechargeEntity.getOutBusinessNo())
                .payAmount(createQuotaOrderAggregate.getActivityOrderEntity().getPayAmount())
                .build();


    }

    protected abstract CreateQuotaOrderAggregate buildOrderAggregate(SkuRechargeEntity skuRechargeEntity, ActivitySkuEntity activitySkuEntity, ActivityEntity activityEntity, ActivityCountEntity activityCountEntity);

}
